package com.velvetantler.weather.view.home

import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.qweather.sdk.response.weather.WeatherHourlyResponse
import com.qweather.sdk.response.weather.WeatherNowResponse
import com.velvetantler.weather.R
import com.velvetantler.weather.WeatherGlobal
import com.velvetantler.weather.adapter.WeatherHourlyItemAdapter
import com.velvetantler.weather.base.BaseBindingFragment
import com.velvetantler.weather.bean.CityInfo
import com.velvetantler.weather.databinding.FragmentHomeBinding
import com.velvetantler.weather.eventBusEvent.ChangeCityClickEvent
import com.velvetantler.weather.utils.LocationUtils
import com.velvetantler.weather.utils.WeatherUtils
import com.velvetantler.weather.view.detail.WeatherDetailActivity
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode.MAIN

class HomeFragment() : BaseBindingFragment<FragmentHomeBinding>(), HomeView {

    private val TAG = "HomeFragment"

    private val handler = Handler(Looper.getMainLooper())

    private lateinit var presenter: HomePresenter

    private lateinit var currentCity: CityInfo

    val locationUtils = LocationUtils()

    private val updateTimeRunnable = object : Runnable {
        override fun run() {
            binding.topBar.tvCurrentTime.text =
                WeatherUtils.formatUTC(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")
            handler.postDelayed(this, 1000)
        }
    }

    override fun onStart() {
        super.onStart()
        EventBus.getDefault().register(this)
    }

    override fun onStop() {
        super.onStop()
        EventBus.getDefault().unregister(this)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 初始化presenter
        presenter = HomePresenter(this, HomeModel())

    }

    override fun initBinding(
        inflater: LayoutInflater,
        parent: ViewGroup?
    ): FragmentHomeBinding {
        return FragmentHomeBinding.inflate(inflater, parent, false)
    }

    override fun initView() {
        // 初始化位置
        checkAndRequestPermission()
        // 当前城市：先写死，后面通过位置获取
        currentCity = CityInfo(
            WeatherGlobal.getCityName(), "110000", WeatherGlobal.getLatitude().toDouble(),
            WeatherGlobal.getLongitude().toDouble()
        )
        // 初始化当前时间
        stopUpdateTime()
        binding.currentWeatherCard.tvWeekday.text =
            WeatherUtils.formatUTC(System.currentTimeMillis(), "EEEE")
        startUpdateTime()
        // 初始化点击事件
        initOnclickEvent()
        // 初始化天气数据
//        initWeatherData()
        // 初始化未来24小时天气列表的间距
        binding.hourlyForecast.rvHourlyForecast.addItemDecoration(object :
            RecyclerView.ItemDecoration() {
            override fun getItemOffsets(
                outRect: Rect,
                view: View,
                parent: RecyclerView,
                state: RecyclerView.State
            ) {
                super.getItemOffsets(outRect, view, parent, state)
                if (parent.getChildAdapterPosition(view) != 0) {
                    outRect.left = WeatherUtils.dip2px(context!!, 10f)
                }
            }
        })
    }

    @SuppressLint("UseCompatLoadingForDrawables", "SetTextI18n")
    override fun getWeatherNowDataSucceed(response: WeatherNowResponse) {
        Toast.makeText(context, "获取天气成功", Toast.LENGTH_SHORT).show()
        val weatherCardView = binding.currentWeatherCard
        weatherCardView.tvTemperature.text = response.now.temp
        weatherCardView.tvWeatherCondition.text = response.now.text
        // 设置天气图标
        val iconCode = '_' + response.now.icon.replace("-", "_")
        val iconId = context?.resources?.getIdentifier(iconCode, "drawable", context?.packageName)
        var drawable: Drawable? = null
        if (iconId != null && iconId != 0) {
            drawable = context?.resources?.getDrawable(iconId, null)
        }
        if (drawable != null) {
            weatherCardView.ivWeatherIcon.setImageDrawable(drawable)
        }
        // 天气描述（多云|西风1级|当前体感30°）
        weatherCardView.tvWeatherCondition.text =
            "${response.now.text} | ${response.now.windDir}${response.now.windScale}级 | 当前体感${response.now.feelsLike}°"
        // 湿度
        weatherCardView.tvHumidity.text = response.now.humidity + "%"
        weatherCardView.tvWindSpeed.text = response.now.windSpeed + "km/h"
        weatherCardView.tvPressure.text = response.now.pressure + " hPa"
        // 更新时间
        weatherCardView.tvRefreshTime.text = WeatherUtils.formatTime(response.now.obsTime)

    }

    override fun getWeatherNowDataFailed(message: String) {
        Log.i("HomeFragment", "getWeatherNowDataFailed: $message")
    }

    override fun getWeatherHourlyDataSucceed(response: WeatherHourlyResponse) {
        Toast.makeText(context, "获取未来24小时天气成功", Toast.LENGTH_SHORT).show()
        // 绑定适配器
        val rvHourlyForecast = binding.hourlyForecast.rvHourlyForecast
        rvHourlyForecast.layoutManager =
            LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
        // 绑定适配器
        rvHourlyForecast.adapter = WeatherHourlyItemAdapter(response.hourly)
    }

    override fun getWeatherHourlyDataFailed(message: String) {
        Log.e(TAG, message)
    }

    override fun getCityListDataSucceed(response: List<CityInfo>) {
        // 1. 打开城市列表Dialog
        val dialog = ChangeCityDialog(
            response,
            currentCity,
            requireContext(),
            R.style.BottomSheetDialog
        )
        dialog.show()
    }

    override fun getCityListDataFailed(message: String) {
        Log.e(TAG, message)
    }

    override fun onDestroy() {
        super.onDestroy()
        stopUpdateTime()
    }

    @Subscribe(threadMode = MAIN)
    fun onChangeCityClickEvent(event: ChangeCityClickEvent) {
        // 1. 获取点击的城市信息
        val cityInfo = event.city
        // 2. 保存当前城市信息
        WeatherGlobal.setCurrentCityAreaCode(cityInfo.adCode)
        WeatherGlobal.setLatitude(cityInfo.latitude.toString())
        WeatherGlobal.setLongitude(cityInfo.longitude.toString())
        WeatherGlobal.setCityName(cityInfo.cityName)
        currentCity = cityInfo
        // 3. 刷新天气信息
        initWeatherData()
    }

    fun initOnclickEvent() {
        // 1. 点击刷新天气
        binding.currentWeatherCard.btnRealTime.setOnClickListener {
            Toast.makeText(context, "点击了刷新天气数据", Toast.LENGTH_SHORT).show()
            presenter.requestWeatherNowData(
                WeatherGlobal.getLongitude(),
                WeatherGlobal.getLatitude()
            )
        }
        // 2. 点击切换城市
        binding.topBar.tvCityName.setOnClickListener {
            presenter.requestCityListData(requireContext())
        }
        binding.topBar.ivDropdown.setOnClickListener {
            presenter.requestCityListData(requireContext())
        }
        // 3. 点击进入天气详情页面
        binding.currentWeatherCard.llCurrentWeatherContainer.setOnClickListener {
            val intent = Intent(requireContext(), WeatherDetailActivity::class.java)
            intent.putExtra("longitude", currentCity.longitude)
            intent.putExtra("latitude", currentCity.latitude)
            intent.putExtra("cityName", currentCity.cityName)
            startActivity(intent)
        }
    }

    val initWeatherData: () -> Unit = {
        currentCity.cityName = WeatherGlobal.getCityName()
        currentCity.latitude = WeatherGlobal.getLatitude().toDouble()
        currentCity.longitude = WeatherGlobal.getLongitude().toDouble()
        // 初始化当前城市
        binding.topBar.tvCityName.text = currentCity.cityName
        // 初始化天气数据
        presenter.requestWeatherNowData(WeatherGlobal.getLongitude(), WeatherGlobal.getLatitude())
        presenter.requestWeatherHourlyData(
            WeatherGlobal.getLongitude(),
            WeatherGlobal.getLatitude()
        )
        // 初始化未来24小时天气的RecycleView
        presenter.requestWeatherHourlyData(
            WeatherGlobal.getLongitude(),
            WeatherGlobal.getLatitude()
        )
    }

    fun startUpdateTime() {
        handler.post(updateTimeRunnable)
    }

    fun stopUpdateTime() {
        handler.removeCallbacks(updateTimeRunnable)
    }

    /**
     * 权限申请官推新方式
     */
    private val requestLocationPermission = registerForActivityResult(
        ActivityResultContracts.RequestPermission()
    ) {
        Log.i(TAG, "onActivityResult: $it")
        if (it) {
            // 获取权限成功
            Toast.makeText(requireContext(), "授权成功！", Toast.LENGTH_SHORT)
            locationUtils.getLocation(requireContext(), initWeatherData)
        } else {
            // 获取权限失败
            Toast.makeText(requireContext(), "授权失败！", Toast.LENGTH_SHORT).show()
        }
    }

    fun checkAndRequestPermission() {
        // 1. 检查系统是否有对应权限
        val hasLocationPermission =
            ActivityCompat.checkSelfPermission(
                requireContext(),
                "android.permission.ACCESS_COARSE_LOCATION"
            )
        if (hasLocationPermission != PackageManager.PERMISSION_GRANTED) { // 0 表示权限被授予 -1 表示权限被拒绝
            // 2. 请求权限
//            // ①传统办法
//            ActivityCompat.requestPermissions(
//                this, // context
//                arrayOf("android.permission.ACCESS_COARSE_LOCATION"), // 权限列表
//                1 // 请求码，相当于于标识该权限申请的ID
//            )
            // ②AndroidX 官方推荐方法
            requestLocationPermission.launch("android.permission.ACCESS_COARSE_LOCATION")
        } else {
            locationUtils.getLocation(requireContext(), initWeatherData)
        }
    }
}